package org.jeecg.modules.demo.mp.controller;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.jeecg.common.api.vo.Result;
import org.jeecg.common.aspect.annotation.AutoLog;
import org.jeecg.common.exception.JeecgBootException;
import org.jeecg.common.system.base.controller.JeecgController;
import org.jeecg.common.system.query.QueryGenerator;
import org.jeecg.common.util.CommonUtils;
import org.jeecg.common.util.oConvertUtils;
import org.jeecg.modules.demo.mp.entity.MpBgUpload;
import org.jeecg.modules.demo.mp.entity.MpBgUploadHis;
import org.jeecg.modules.demo.mp.entity.MpBudget;
import org.jeecg.modules.demo.mp.service.IMpBgUploadHisService;
import org.jeecg.modules.demo.mp.service.IMpBgUploadService;
import org.jeecg.modules.demo.mp.service.IMpBudgetService;
import org.jeecg.modules.demo.mp.util.MPParser;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.MultipartHttpServletRequest;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.*;

/**
 * @Description: Budget Upload
 * @Author: jeecg-boot
 * @Date: 2022-06-30
 * @Version: V1.0
 */
@Api(tags = "Budget Upload")
@RestController
@RequestMapping("/mp/mpBgUpload")
@Slf4j
public class MpBgUploadController extends JeecgController<MpBgUpload, IMpBgUploadService> {
    @Autowired
    private IMpBgUploadService mpBgUploadService;
    @Autowired
    private IMpBgUploadHisService mpBgUploadHisService;


    @Autowired
    private IMpBudgetService mpBudgetService;

    @Autowired
    private JdbcTemplate jdbcTemplate;

    /**
     * 本地：local minio：minio 阿里：alioss
     */
    @Value(value = "${jeecg.uploadType}")
    private String uploadType;

    @Value(value = "${jeecg.path.upload}")
    private String uploadpath;


    /**
     * 分页列表查询
     *
     * @param mpBgUpload
     * @param pageNo
     * @param pageSize
     * @param req
     * @return
     */
    //@AutoLog(value = "Budget Upload-分页列表查询")
    @ApiOperation(value = "Budget Upload-分页列表查询", notes = "Budget Upload-分页列表查询")
    @GetMapping(value = "/list")
    public Result<IPage<MpBgUpload>> queryPageList(MpBgUpload mpBgUpload,
                                                   @RequestParam(name = "pageNo", defaultValue = "1") Integer pageNo,
                                                   @RequestParam(name = "pageSize", defaultValue = "10") Integer pageSize,
                                                   HttpServletRequest req) {
        QueryWrapper<MpBgUpload> queryWrapper = QueryGenerator.initQueryWrapper(mpBgUpload, req.getParameterMap());

        //        只加载当期
        String currVersion = getCurrVersion("Budget");
        queryWrapper.eq("version", currVersion);

        Page<MpBgUpload> page = new Page<MpBgUpload>(pageNo, pageSize);
        IPage<MpBgUpload> pageList = mpBgUploadService.page(page, queryWrapper);
        return Result.OK(pageList);
    }

    /**
     * 添加
     *
     * @param mpBgUpload
     * @return
     */
    @AutoLog(value = "Budget Upload-添加")
    @ApiOperation(value = "Budget Upload-添加", notes = "Budget Upload-添加")
    @PostMapping(value = "/add")
    public Result<String> add(@RequestBody MpBgUpload mpBgUpload) {
        mpBgUploadService.save(mpBgUpload);
        return Result.OK("添加成功！");
    }

    /**
     * 编辑
     *
     * @param mpBgUpload
     * @return
     */
    @AutoLog(value = "Budget Upload-编辑")
    @ApiOperation(value = "Budget Upload-编辑", notes = "Budget Upload-编辑")
    @RequestMapping(value = "/edit", method = {RequestMethod.PUT, RequestMethod.POST})
    public Result<String> edit(@RequestBody MpBgUpload mpBgUpload) {
        mpBgUploadService.updateById(mpBgUpload);
        return Result.OK("编辑成功!");
    }

    /**
     * 通过id删除
     *
     * @param id
     * @return
     */
    @AutoLog(value = "Budget Upload-通过id删除")
    @ApiOperation(value = "Budget Upload-通过id删除", notes = "Budget Upload-通过id删除")
    @DeleteMapping(value = "/delete")
    public Result<String> delete(@RequestParam(name = "id", required = true) String id) {
        mpBgUploadService.removeById(id);
        return Result.OK("删除成功!");
    }

    /**
     * 批量删除
     *
     * @param ids
     * @return
     */
    @AutoLog(value = "Budget Upload-批量删除")
    @ApiOperation(value = "Budget Upload-批量删除", notes = "Budget Upload-批量删除")
    @DeleteMapping(value = "/deleteBatch")
    public Result<String> deleteBatch(@RequestParam(name = "ids", required = true) String ids) {
        this.mpBgUploadService.removeByIds(Arrays.asList(ids.split(",")));
        return Result.OK("批量删除成功!");
    }

    /**
     * 通过id查询
     *
     * @param id
     * @return
     */
    //@AutoLog(value = "Budget Upload-通过id查询")
    @ApiOperation(value = "Budget Upload-通过id查询", notes = "Budget Upload-通过id查询")
    @GetMapping(value = "/queryById")
    public Result<MpBgUpload> queryById(@RequestParam(name = "id", required = true) String id) {
        MpBgUpload mpBgUpload = mpBgUploadService.getById(id);
        if (mpBgUpload == null) {
            return Result.error("未找到对应数据");
        }
        return Result.OK(mpBgUpload);
    }

    /**
     * 导出excel
     *
     * @param request
     * @param mpBgUpload
     */
    @RequestMapping(value = "/exportXls")
    public ModelAndView exportXls(HttpServletRequest request, MpBgUpload mpBgUpload) {
        return super.exportXls(request, mpBgUpload, MpBgUpload.class, "Budget Upload");
    }

    /**
     * 通过excel导入数据
     *
     * @param request
     * @param response
     * @return
     */
    @RequestMapping(value = "/importExcel", method = RequestMethod.POST)
    public Result<?> importExcel(HttpServletRequest request, HttpServletResponse response) {
        return super.importExcel(request, response, MpBgUpload.class);
    }


    /**
     * 通过excel导入数据
     *
     * @param request
     * @param response
     * @return
     */
    @RequestMapping(value = "/importExcelByDivision", method = RequestMethod.POST)
    public Result<?> importExcelByDivision(HttpServletRequest request, HttpServletResponse response) {
        Result<?> result = new Result<>();
        String savePath = "";
        String bizPath = "masterplan";

        //LOWCOD-2580 sys/common/upload接口存在任意文件上传漏洞
        if (oConvertUtils.isNotEmpty(bizPath) && (bizPath.contains("../") || bizPath.contains("..\\"))) {
            throw new JeecgBootException("上传目录bizPath，格式非法！");
        }

        MultipartHttpServletRequest multipartRequest = (MultipartHttpServletRequest) request;

        Map<String, MultipartFile> filesMap = multipartRequest.getFileMap();
        String recordId = (String) (filesMap.keySet().toArray())[0];

        // 获取上传文件对象
        MultipartFile file = multipartRequest.getFile(recordId);
        if (oConvertUtils.isEmpty(bizPath)) {
            bizPath = "";
        }

        // local本地保存
        savePath = CommonUtils.uploadLocal(file, bizPath, uploadpath);
        if (oConvertUtils.isNotEmpty(savePath)) {
            result.setMessage(savePath);
            result.setSuccess(true);

            MpBgUpload vo = mpBgUploadService.getBaseMapper().selectById(recordId);
            //获取当前版本
            String currVersion;
            if (vo == null) {
                currVersion = getCurrVersion("Budget");
                if (currVersion == null) {
                    throw new JeecgBootException("请设置Budget的工作版本！");
                }
            } else {
                currVersion = vo.getVersion();
            }

            //  解析预算数据
            List<MpBudget> bgList = null;
            try {
                bgList = MPParser.parseBudget(file.getInputStream(), currVersion);
            } catch (Exception e) {
                e.printStackTrace();
            }
            Map<String, List<MpBudget>> bgByDivision = new HashMap<String, List<MpBudget>>();
            if (bgList != null && !bgList.isEmpty()) {
                // 提取数据不为空
//				按照division进行遍历，分别保存
                for (MpBudget bg : bgList) {
                    bg.setVersion(currVersion);

                    List<MpBudget> divisionList = bgByDivision.get(bg.getDivision());
                    if (divisionList == null) {
                        divisionList = new ArrayList<MpBudget>();
                        bgByDivision.put(bg.getDivision(), divisionList);
                    }
                    divisionList.add(bg);
                }


                QueryWrapper<MpBgUpload> queryWrapper = new QueryWrapper<MpBgUpload>();
                queryWrapper.eq("version", currVersion);
                queryWrapper.in("division", bgByDivision.keySet());
                List<MpBgUpload> uploadList = mpBgUploadService.list(queryWrapper);
                List<MpBgUploadHis> uploadHisList =new ArrayList<MpBgUploadHis> ();
                for (MpBgUpload e : uploadList) {
//                    更新版本信息
                    e.setFiles(savePath);
                    e.setFileName(file.getOriginalFilename().substring(0, 20) + "...");
//              增加版本变动数据说明
                    e.setComment("本次更新" + bgByDivision.get(e.getDivision()).size() + "条");
                    // 版本+1
                    e.setRevision(e.getRevision() + 1);

                    MpBgUploadHis eHis = copyToUploadHis(e);
                    uploadHisList.add(eHis);

//                    更新版本信息
                    List<MpBudget> divisionBgList = bgByDivision.get(e.getDivision());
                    for (MpBudget bg : divisionBgList) {
                        bg.setRevision(e.getRevision());
                        // 记录版本号
                        bg.setBatchid(e.getId());
                    }
                }

//               相同数据维度，更新原纪录的ID和createtime
                QueryWrapper<MpBudget> queryWrapper4Bg = new QueryWrapper<MpBudget>();
                queryWrapper4Bg.eq("version", currVersion);
                queryWrapper4Bg.in("division", bgByDivision.keySet());
                List<MpBudget> dbBgList = mpBudgetService.list(queryWrapper4Bg);
                Map<String,MpBudget> dbBgMap = new HashMap<String, MpBudget>();
                for (MpBudget bg : dbBgList) {
                    dbBgMap.put(bg.getDimKey(),bg);
                }
                for (MpBudget bg : bgList) {
                    if(dbBgMap.containsKey(bg.getDimKey())){
                        MpBudget dbBg = dbBgMap.get(bg.getDimKey());
                        bg.setCreateBy(dbBg.getCreateBy());
                        bg.setCreateTime(dbBg.getCreateTime());
                        bg.setId(dbBg.getId());
                    }

                }


//                保存预算版本数据
                mpBgUploadService.saveOrUpdateBatch(uploadList);
                mpBgUploadHisService.saveOrUpdateBatch(uploadHisList);

//保存预算数据
                mpBudgetService.saveOrUpdateBatch(bgList);
                // TODO  生成历史记录

            }


////            更新record记录
//            if (vo != null) {
//                vo.setFiles(savePath);
//                vo.setFileName(file.getOriginalFilename());
//                // 版本+1
//                vo.setRevision(vo.getRevision() + 1);
//
//                mpBgUploadService.updateById(vo);
//            }


        } else {
            result.setMessage("上传失败！");
            result.setSuccess(false);
        }
        return result;
    }

    private MpBgUploadHis copyToUploadHis(MpBgUpload mp) {
        MpBgUploadHis mpHis = new MpBgUploadHis();
        mpHis.setBatchid(mp.getId());
        mpHis.setCreateBy(mp.getCreateBy());
        mpHis.setCreateTime(mp.getCreateTime());
        mpHis.setUpdateBy(mp.getUpdateBy());
        mpHis.setUpdateTime(mp.getUpdateTime());
        mpHis.setVersion(mp.getVersion());
        mpHis.setDivision(mp.getDivision());
        mpHis.setRevision(mp.getRevision());
        mpHis.setFiles(mp.getFiles());
        mpHis.setFileName(mp.getFileName());
        mpHis.setComment(mp.getComment());

        return mpHis;
    }
    private String getCurrVersion(String typ) {
        String currVersion;
        String sql = "SELECT version FROM mp_period where typ='" + typ + "' and iscurrent=1";
        currVersion = jdbcTemplate.queryForObject(sql, String.class);
        return currVersion;
    }
}
